<template>
    <a-modal
      title="添加创意素材"
      v-model:visible="localVisible"
      :maskClosable="false"
      :destroyOnClose="false"
      :confirmLoading="loading"
      width="1100px"
      height="600px"
      @ok="save"
    >
      <a-form :label-col="{ style: { width: '100px', minWidth: '100px' } }">
        <a-form-item label="创意方式">
          <span style="color: #666">{{ creativeType }}</span>
        </a-form-item>
  
        <a-form-item label="素材内容">
          <a-form-item-rest>
            <div class="material-container">
              <div class="top">
                <div class="package-container">
                  <div class="package">
                    <div
                      v-for="(_, i) in creativePackage"
                      :key="i"
                      class="package-item"
                      :class="{ active: activeIndex === i }"
                      @click="activeIndex = i"
                    >
                      创意包 {{ i + 1 }}
                      <span v-if="creativePackage.length > 1" class="delete-icon" @click.stop="deleteCreativePackage(i)">×</span>
                    </div>
                  </div>
                </div>
                <div>
                  <a-button type="primary" class="add-package-btn" @click="addCreativePackage" :disabled="isMaxPackageCount">
                    +添加创意包
                  </a-button>
                </div>
              </div>
              <div class="content">
                <div class="type-container">
                  <div
                    v-for="item in materialTypeConfig"
                    :key="item.type"
                    class="type-item"
                    :class="{ active: currentPackage.active === item.type }"
                    @click="currentPackage.active = item.type"
                  >
                    <div class="type-icon">
                      <img :src="getIconSrc(item.type)" alt="" class="material-icon" />
                    </div>
                    <div class="type-name">{{ item.name }}</div>
                    <div v-if="getMaterialCount(item.type) > 0" class="material-count">{{ getMaterialCount(item.type) }}</div>
                  </div>
                </div>
                <div class="tip">
                  素材格式
                  <a-popover placement="top" trigger="hover">
                    <template #content>
                      <div class="tip-content">
                        <div v-for="(text, index) in getTipText" :key="index">{{ text }}</div>
                      </div>
                    </template>
                    <question-circle-outlined style="margin-left: 5px; color: #1890ff" />
                  </a-popover>
                </div>
                <div class="materials-wrapper">
                  <div
                    v-if="currentPackage.active === 'package3Pic' && currentPackage['package3Pic'] && (currentPackage['package3Pic'] as MaterialItem[]).length % 3 !== 0"
                    class="group-warning"
                  >
                    注意：组图需要3的倍数张图片，当前有 {{ (currentPackage["package3Pic"] as MaterialItem[]).length }} 张图片
                  </div>
                  <div class="materials">
                    <!-- 处理组图（类型3）的特殊显示 -->
                    <template v-if="currentPackage.active === 'package3Pic'">
                      <div v-for="(group, groupIndex) in getGroupedImages()" :key="groupIndex" class="group-item">
                        <div v-for="(item, itemIndex) in group" :key="itemIndex" class="material-item group-material-item">
                          <a-popover placement="right" trigger="hover" :overlayStyle="{ padding: 0 }" :mouseEnterDelay="0.3">
                            <template #content>
                              <div class="preview-container">
                                <div class="preview-content">
                                  <img :src="getImageUrl(item.Thumb)" alt="" class="preview-image" />
                                </div>
                                <div class="preview-info">
                                  <div class="preview-name" :title="item.Name || ''">{{ item.Name || "" }}</div>
                                  <div class="preview-details">
                                    <span class="preview-size">{{ formattedSize(item.FileSize || 0) }}</span>
                                    <span v-if="item.Width && item.Height" class="preview-dimensions"
                                      >{{ item.Width }}×{{ item.Height }}</span
                                    >
                                  </div>
                                </div>
                              </div>
                            </template>
                            <div class="material-content">
                              <img :src="getImageUrl(item.Thumb)" alt="" />
                            </div>
                          </a-popover>
                          <div class="replace-material" @click.stop="replaceMaterial('package3Pic', groupIndex * 3 + itemIndex)">
                            替换
                          </div>
                        </div>
                        <div class="delete-material group-delete" @click.stop="deleteGroupMaterial(groupIndex)">×</div>
                      </div>
                    </template>
  
                    <!-- 处理其他类型的素材 -->
                    <template v-else>
                      <div
                        v-for="(item, i) in (currentPackage[currentPackage.active as string] || [])"
                        :key="i"
                        class="material-item"
                        :class="{ 'video-material-item': isVideoType(currentPackage.active) }"
                      >
                        <!-- 素材内容 -->
                        <a-popover placement="right" trigger="hover" :overlayStyle="{ padding: 0 }" :mouseEnterDelay="0.3">
                          <template #content>
                            <div class="preview-container">
                              <div class="preview-content">
                                <img :src="getImageUrl(item.previewUrl)" alt="" class="preview-image" />
                                <div v-if="materialsType() === 'video'" class="video-preview-container">
                                  <video :src="getImageUrl(item.previewVideoUrl)" class="preview-video" autoplay loop controls></video>
                                </div>
                              </div>
                              <div class="preview-info">
                                <div class="preview-name" :title="item.Name || ''">{{ item.Name || "" }}</div>
                                <div class="preview-details">
                                  <span class="preview-size">{{ formattedSize(item.FileSize || 0) }}</span>
                                  <span v-if="item.Width && item.Height" class="preview-dimensions"
                                    >{{ item.Width }}×{{ item.Height }}</span
                                  >
                                </div>
                              </div>
                            </div>
                          </template>
  
                          <!-- 视频类型显示选择视频和封面的界面 -->
                          <div v-if="isVideoType(currentPackage.active)" class="material-content video-material">
                            <div class="video-selection-container">
                              <div class="video-selection-box" @click="selectVideo(i)">
                                <div v-if="item.Thumb" class="video-preview">
                                  <img :src="getImageUrl(item.Thumb)" alt="" />
                                </div>
                                <div v-else class="video-empty">
                                  <div class="select-text">选择视频</div>
                                </div>
                              </div>
  
                              <div class="cover-selection-box">
                                <div
                                  v-if="item.customCover || item.Cover"
                                  class="cover-preview"
                                  @click="props.allowChangeCover ? changeCover(i) : undefined"
                                  :style="{ cursor: props.allowChangeCover ? 'pointer' : 'default' }"
                                >
                                  <img
                                    :src="
                                      getImageUrl(
                                        item.customCover
                                          ? typeof item.customCover === 'object'
                                            ? item.customCover.Thumb || item.customCover.thumb
                                            : item.customCover
                                          : typeof item.Cover === 'object'
                                          ? item.Cover.Thumb || item.Cover.thumb
                                          : item.Cover
                                      )
                                    "
                                    alt=""
                                  />
                                </div>
                                <div v-else class="cover-empty" @click="props.allowChangeCover ? changeCover(i) : undefined">
                                  <div class="select-text">推荐封面</div>
                                </div>
                                <div v-if="props.allowChangeCover" class="cover-options">
                                  <div class="option-btn" @click="changeCover(i)">封面</div>
                                </div>
                              </div>
                            </div>
                          </div>
  
                          <!-- 非视频类型正常显示 -->
                          <div v-else class="material-content">
                            <img :src="getImageUrl(item.Thumb)" alt="" />
                          </div>
                        </a-popover>
                        <div class="delete-material" @click.stop="deleteMaterial(i)">×</div>
                        <div class="replace-material" @click.stop="replaceMaterial(currentPackage.active, i)">替换</div>
                        <div
                          v-if="isVideoType(currentPackage.active) && props.allowChangeCover"
                          class="change-cover"
                          @click.stop="changeCover(i)"
                        >
                          更换封面
                        </div>
                      </div>
                    </template>
  
                    <div class="add-material" @click="addMaterials">
                      <div class="add-icon">+</div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </a-form-item-rest>
        </a-form-item>
      </a-form>
    </a-modal>
  
    <SelectMaterials ref="selectMaterialsRef" @selectedVideos="selectVideos" @selectedImages="selectImages" />
  </template>
  
  <script setup lang="ts">
  import { ref, computed } from "vue";
  import { message } from "ant-design-vue";
  import { QuestionCircleOutlined } from "@ant-design/icons-vue";
  import _ from "lodash";
  import SelectMaterials from "./SelectMaterials.vue";
  
  import { formattedSize } from "@/pages/NewBatchCreateAd/tool";
  
  // 定义素材类型配置接口
  interface MaterialTypeItem {
    type: string;
    name: string;
    icon?: string;
  }
  
  // 定义素材项接口
  interface MaterialItem {
    Thumb?: string;
    Name?: string;
    FileSize?: number;
    previewUrl?: string;
    previewVideoUrl?: string;
    customCover?: string | any;
    Cover?: any;
    CoverMd5?: string;
    Md5?: string;
    md5?: string;
    Width?: number;
    Height?: number;
    [key: string]: any;
  }
  
  // 定义创意包类型接口
  interface CreativePackageItem {
    active: string;
    [key: string]: MaterialItem[] | string;
  }
  
  // 修改props定义
  const props = defineProps({
    visible: {
      type: Boolean,
      default: false,
    },
    // 创意方式
    creativeType: {
      type: String,
      default: "程序化创意",
    },
    // 素材类型配置
    materialTypes: {
      type: Array as () => MaterialTypeItem[],
      default: () => [
        { type: "largePic", name: "大图" },
        { type: "singlePic", name: "小图" },
        { type: "package3Pic", name: "组图" },
        { type: "verticalVideos", name: "竖版视频" },
        { type: "horizontalVideos", name: "横版视频" },
      ],
    },
    // 素材提示文本配置
    tipTextConfig: {
      type: Object as () => Record<string, string[]>,
      default: () => ({
        largePic: ["宽高比16:9", "尺寸>=960×540", "JPG、JPEG、PNG格式", "<500KB"],
        singlePic: ["宽高比3:2", "尺寸>=480×320", "JPG、JPEG、PNG格式", "<500KB"],
        package3Pic: ["宽高比3:2", "尺寸>=480×320", "JPG、JPEG、PNG格式", "<500KB"],
        verticalVideos: ["宽高比9:16", "尺寸>=540×960", "4~120秒", "<50MB", "MP4格式，需要有声音", "封面尺寸与视频一致，<500KB"],
        horizontalVideos: ["宽高比16:9", "尺寸>=960×540", "4~120秒", "<50MB", "MP4格式，需要有声音", "封面尺寸与视频一致，<500KB"],
      }),
    },
    // 最大创意包数量配置
    maxPackageCount: {
      type: Number,
      default: 10,
    },
    // 是否允许替换视频封面
    allowChangeCover: {
      type: Boolean,
      default: true,
    },
  });
  
  const emit = defineEmits(["update:visible", "save"]);
  
  const localVisible = ref(false);
  
  const selectMaterialsRef = ref<any>(null);
  
  const loading = ref(false);
  
  // 使用传入的素材类型配置
  const materialTypeConfig = computed(() => props.materialTypes);
  
  // 初始化创意包方法
  const initializeCreativePackage = () => {
    const pkg: CreativePackageItem = {
      active: "largePic",
    };
  
    // 为每个素材类型初始化空数组
    materialTypeConfig.value.forEach((item) => {
      pkg[item.type] = [];
    });
  
    return pkg;
  };
  
  // 创意包
  const creativePackage = ref<CreativePackageItem[]>([initializeCreativePackage()]);
  
  // 当前选中的创意包索引
  const activeIndex = ref(0);
  
  // 当前选中的创意包
  const currentPackage = computed(() => creativePackage.value[activeIndex.value]);
  
  // 根据当前选中的素材类型获取对应的提示文本
  const getTipText = computed(() => {
    const activeType = currentPackage.value.active;
    return props.tipTextConfig[activeType] || [];
  });
  
  // 计算是否已达到最大创意包数量
  const isMaxPackageCount = computed(() => {
    return creativePackage.value.length >= props.maxPackageCount;
  });
  
  // 添加创意包方法
  const addCreativePackage = () => {
    // 判断当前创意包数量是否已达到最大值
    if (creativePackage.value.length >= props.maxPackageCount) {
      message.warning(`最多只能创建${props.maxPackageCount}个创意包`);
      return;
    }
  
    creativePackage.value.push(initializeCreativePackage());
  };
  
  // 获取图标路径
  const getIconSrc = (type: string) => {
    const iconMap: Record<string, string> = {
      largePic:
        'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><rect x="2" y="4" width="20" height="16" rx="1" fill="none" stroke="%23999" stroke-width="1"/><rect x="6" y="8" width="12" height="8" fill="%23ccc"/></svg>',
      singlePic:
        'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><rect x="2" y="4" width="20" height="16" rx="1" fill="none" stroke="%23999" stroke-width="1"/><rect x="8" y="8" width="8" height="8" fill="%23ccc"/></svg>',
      package3Pic:
        'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><rect x="2" y="4" width="20" height="16" rx="1" fill="none" stroke="%23999" stroke-width="1"/><rect x="4" y="7" width="4" height="10" fill="%23ccc"/><rect x="10" y="7" width="4" height="10" fill="%23ccc"/><rect x="16" y="7" width="4" height="10" fill="%23ccc"/></svg>',
      verticalVideos:
        'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><rect x="6" y="2" width="12" height="20" rx="1" fill="none" stroke="%23999" stroke-width="1"/><polygon points="10,8 16,12 10,16" fill="%23ccc"/></svg>',
      horizontalVideos:
        'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><rect x="2" y="6" width="20" height="12" rx="1" fill="none" stroke="%23999" stroke-width="1"/><polygon points="9,9 15,12 9,15" fill="%23ccc"/></svg>',
    };
    return iconMap[type] || "";
  };
  
  const addMaterials = () => {
    let str = "images";
    switch (currentPackage.value.active) {
      case "largePic":
        str = "images";
        break;
      case "singlePic":
        str = "images";
        break;
      case "package3Pic":
        str = "images";
        break;
      case "verticalVideos":
        str = "videos";
        break;
      case "horizontalVideos":
        str = "videos";
        break;
    }
    selectMaterialsRef.value.show(str);
  };
  
  // 替换素材
  const replaceMaterial = (type: string, index: number) => {
    // 保存当前要替换的素材类型和索引
    const replaceInfo: { type: string; index: number } = {
      type,
      index,
    };
  
    // 根据类型决定打开图片选择器还是视频选择器
    let materialType = "images";
    if (type === "verticalVideos" || type === "horizontalVideos") {
      materialType = "videos";
    }
  
    // 打开素材选择器，并传入替换模式标志
    selectMaterialsRef.value.show(materialType, true, replaceInfo);
  };
  
  // 视频处理方法
  const selectVideos = (videos: any[], isReplace = false, replaceInfo: { type: string; index: number } | null = null) => {
    if (isReplace && replaceInfo) {
      // 替换模式：只取第一个视频进行替换
      if (videos.length > 0) {
        try {
          // 直接替换数组中的元素
          const type = replaceInfo.type;
          const index = replaceInfo.index;
  
          // 确保数组已初始化
          if (!creativePackage.value[activeIndex.value][type]) {
            creativePackage.value[activeIndex.value][type] = [];
          }
  
          // 如果索引超出范围，则添加到末尾
          if (index >= (creativePackage.value[activeIndex.value][type] as MaterialItem[]).length) {
            (creativePackage.value[activeIndex.value][type] as MaterialItem[]).push(videos[0]);
          } else {
            // 否则替换指定位置的元素
            (creativePackage.value[activeIndex.value][type] as MaterialItem[]).splice(index, 1, videos[0]);
          }
        } catch (error) {
          console.error("替换视频时出错", error);
        }
      }
    } else {
      // 添加模式：添加所有视频
      try {
        const activeType = currentPackage.value.active;
        // 确保数组已初始化
        if (!creativePackage.value[activeIndex.value][activeType]) {
          creativePackage.value[activeIndex.value][activeType] = [];
        }
  
        videos.forEach((video: any) => {
          (creativePackage.value[activeIndex.value][activeType] as MaterialItem[]).push(video);
        });
      } catch (error) {
        console.error("添加视频时出错", error);
      }
    }
  };
  
  // 图片处理方法
  const selectImages = (
    images: any[],
    isReplace = false,
    replaceInfo: { type: string; index: number } | null = null,
    isCoverSelection = false,
    coverInfo: { videoIndex: number; videoType: string } | null = null
  ) => {
    // 处理视频封面选择
    if (isCoverSelection && coverInfo && images.length > 0) {
      try {
        const { videoIndex, videoType } = coverInfo;
  
        // 确保视频数组存在
        if (!creativePackage.value[activeIndex.value][videoType]) {
          return;
        }
  
        // 确保视频索引有效
        if (videoIndex >= 0 && videoIndex < (creativePackage.value[activeIndex.value][videoType] as MaterialItem[]).length) {
          // 设置自定义封面 - 保存整个对象而不仅仅是路径
          (creativePackage.value[activeIndex.value][videoType] as MaterialItem[])[videoIndex].customCover = images[0];
          message.success("视频封面已更新");
        }
        return;
      } catch (error) {
        console.error("设置视频封面时出错", error);
        message.error("设置视频封面失败");
        return;
      }
    }
  
    // 原有的替换和添加逻辑保持不变
    if (isReplace && replaceInfo) {
      // 替换模式
      if (images.length > 0) {
        try {
          // 直接替换数组中的元素
          const type = replaceInfo.type;
          const index = replaceInfo.index;
  
          // 确保数组已初始化
          if (!creativePackage.value[activeIndex.value][type]) {
            creativePackage.value[activeIndex.value][type] = [];
          }
  
          // 如果索引超出范围，则添加到末尾
          if (index >= (creativePackage.value[activeIndex.value][type] as MaterialItem[]).length) {
            (creativePackage.value[activeIndex.value][type] as MaterialItem[]).push(images[0]);
          } else {
            // 否则替换指定位置的元素
            (creativePackage.value[activeIndex.value][type] as MaterialItem[]).splice(index, 1, images[0]);
          }
        } catch (error) {
          console.error("替换图片时出错", error);
        }
      }
    } else {
      // 添加模式
      try {
        const activeType = currentPackage.value.active;
        if (activeType === "package3Pic") {
          // 组图添加逻辑
          const imagesCopy = [...images];
  
          while (imagesCopy.length > 0) {
            const groupImages = imagesCopy.splice(0, 3);
  
            // 确保数组已初始化
            if (!creativePackage.value[activeIndex.value][activeType]) {
              creativePackage.value[activeIndex.value][activeType] = [];
            }
  
            groupImages.forEach((image: any) => {
              (creativePackage.value[activeIndex.value][activeType] as MaterialItem[]).push(image);
            });
          }
        } else {
          // 其他类型正常添加
          // 确保数组已初始化
          if (!creativePackage.value[activeIndex.value][activeType]) {
            creativePackage.value[activeIndex.value][activeType] = [];
          }
  
          images.forEach((image: any) => {
            (creativePackage.value[activeIndex.value][activeType] as MaterialItem[]).push(image);
          });
        }
      } catch (error) {
        console.error("添加图片时出错", error);
      }
    }
  };
  
  // 获取组图分组后的数据
  const getGroupedImages = () => {
    const images = (currentPackage.value["package3Pic"] as MaterialItem[]) || [];
    const groups = [];
  
    // 按照3张一组进行分组
    for (let i = 0; i < images.length; i += 3) {
      // 修改这里，不再要求必须有3张图片才显示一组
      const group = [];
      for (let j = 0; j < 3 && i + j < images.length; j++) {
        group.push(images[i + j]);
      }
      if (group.length > 0) {
        groups.push(group);
      }
    }
  
    return groups;
  };
  
  // 删除组图
  const deleteGroupMaterial = (groupIndex: number) => {
    if (!currentPackage.value || !currentPackage.value["package3Pic"]) {
      return;
    }
  
    // 计算要删除的图片数量（可能不足3张）
    const startIndex = groupIndex * 3;
    const endIndex = Math.min(startIndex + 3, (currentPackage.value["package3Pic"] as MaterialItem[]).length);
    const count = endIndex - startIndex;
  
    // 删除这组图片
    (currentPackage.value["package3Pic"] as MaterialItem[]).splice(startIndex, count);
  };
  
  // 获取素材数量
  const getMaterialCount = (type: string) => {
    if (!currentPackage.value || !currentPackage.value[type]) {
      return 0;
    }
    return (currentPackage.value[type] as MaterialItem[]).length;
  };
  
  // 删除素材
  const deleteMaterial = (index: number) => {
    const activeType = currentPackage.value.active;
    if (!currentPackage.value || !currentPackage.value[activeType]) {
      return;
    }
    (currentPackage.value[activeType] as MaterialItem[]).splice(index, 1);
  };
  
  // 判断是否为图片
  const materialsType = () => {
    const type = currentPackage.value.active;
    switch (type) {
      case "largePic":
      case "singlePic":
      case "package3Pic":
        return "image";
      case "verticalVideos":
      case "horizontalVideos":
        return "video";
    }
  };
  
  // 保存
  const save = () => {
    // 验证每个创意包是否有素材
    const emptyPackages = [];
    const invalidGroupPackages = [];
  
    for (let i = 0; i < creativePackage.value.length; i++) {
      const pkg = creativePackage.value[i];
      let hasContent = false;
  
      // 检查每种类型是否有素材
      for (const type of materialTypeConfig.value.map((item) => item.type)) {
        if (pkg[type] && (pkg[type] as MaterialItem[]).length > 0) {
          hasContent = true;
  
          // 检查组图是否为3的倍数
          if (type === "package3Pic" && (pkg[type] as MaterialItem[]).length % 3 !== 0) {
            invalidGroupPackages.push(i + 1);
          }
        }
      }
  
      if (!hasContent) {
        emptyPackages.push(i + 1);
      }
    }
  
    // 如果有空的创意包，提示用户
    if (emptyPackages.length > 0) {
      const packageNames = emptyPackages.map((index) => `创意包 ${index}`).join("、");
      message.error(`${packageNames} 没有添加任何素材，请添加素材后再保存`);
      return;
    }
  
    // 如果有组图不是3的倍数，提示用户
    if (invalidGroupPackages.length > 0) {
      const packageNames = invalidGroupPackages.map((index) => `创意包 ${index}`).join("、");
      message.error(`${packageNames} 中的组图数量不是3的倍数，请调整后再保存`);
      return; // 这里返回，不关闭窗口
    }
  
    // 处理视频封面
    for (let i = 0; i < creativePackage.value.length; i++) {
      const pkg = creativePackage.value[i];
  
      // 处理竖版视频
      if (pkg["verticalVideos"] && (pkg["verticalVideos"] as MaterialItem[]).length > 0) {
        (pkg["verticalVideos"] as MaterialItem[]).forEach((video: any) => {
          // 如果有自定义封面，使用自定义封面
          if (video.customCover) {
            // 添加标识属性
            if (typeof video.customCover === "object") {
              video.customCover.IsCover = true;
              video.customCover.isCover = true;
            }
  
            video.Cover = video.customCover;
            // 确保Cover对象也有标识属性
            if (typeof video.Cover === "object") {
              video.Cover.IsCover = true;
              video.Cover.isCover = true;
            }
  
            video.CoverMd5 = video.customCover.Md5 || video.customCover.md5;
          } else if (video.Cover && typeof video.Cover === "object") {
            // 如果只有默认封面，也添加标识
            video.Cover.IsCover = true;
            video.Cover.isCover = true;
          }
        });
      }
  
      // 处理横版视频
      if (pkg["horizontalVideos"] && (pkg["horizontalVideos"] as MaterialItem[]).length > 0) {
        (pkg["horizontalVideos"] as MaterialItem[]).forEach((video: any) => {
          // 如果有自定义封面，使用自定义封面
          if (video.customCover) {
            // 添加标识属性
            if (typeof video.customCover === "object") {
              video.customCover.IsCover = true;
              video.customCover.isCover = true;
            }
  
            video.Cover = video.customCover;
            // 确保Cover对象也有标识属性
            if (typeof video.Cover === "object") {
              video.Cover.IsCover = true;
              video.Cover.isCover = true;
            }
  
            video.CoverMd5 = video.customCover.Md5 || video.customCover.md5;
          } else if (video.Cover && typeof video.Cover === "object") {
            // 如果只有默认封面，也添加标识
            video.Cover.IsCover = true;
            video.Cover.isCover = true;
          }
        });
      }
    }
  
    // lodash克隆创意包数据
    const clonedCreativePackage = _.cloneDeep(creativePackage.value);
    // 循环删除active属性
    clonedCreativePackage.forEach((pkg: any) => {
      delete pkg.active;
    });
    // 将创意包数据发送给父组件
    emit("save", clonedCreativePackage);
  
    // 重置创意包数据
    resetCreativePackage();
  
    // 隐藏弹框
    hide();
  };
  
  // 重置创意包方法
  const resetCreativePackage = () => {
    // 重置为初始状态
    creativePackage.value = [initializeCreativePackage()];
    activeIndex.value = 0;
  };
  
  // 显示弹框
  const show = () => {
    localVisible.value = true;
  };
  
  // 隐藏弹框
  const hide = () => {
    localVisible.value = false;
  };
  
  // 暴露方法给父组件
  defineExpose({
    show,
    hide,
    resetCreativePackage,
  });
  
  // 添加默认图片
  const defaultImageUrl =
    'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><rect width="24" height="24" fill="%23f0f0f0"/><text x="12" y="12" font-size="8" text-anchor="middle" alignment-baseline="middle" fill="%23999">无图</text></svg>';
  
  // 获取图片URL的方法
  const getImageUrl = (thumb: string | undefined) => {
    if (!thumb) return defaultImageUrl;
    const url = "http://td.dev.txstandard.sf";
    return url + thumb;
  };
  
  // 判断是否为视频类型
  const isVideoType = (type: string) => {
    return type === "verticalVideos" || type === "horizontalVideos";
  };
  
  // 更换视频封面
  const changeCover = (index: number) => {
    const activeType = currentPackage.value.active;
    if (!isVideoType(activeType)) return;
  
    // 打开素材选择器，选择图片作为封面，并设置单选模式
    selectMaterialsRef.value.show("images", false, null, true, {
      videoIndex: index,
      videoType: activeType,
    });
  };
  
  // 选择视频
  const selectVideo = (index: number) => {
    const activeType = currentPackage.value.active;
    if (!isVideoType(activeType)) return;
  
    // 打开素材选择器，选择视频
    selectMaterialsRef.value.show("videos", true, {
      type: activeType,
      index: index,
    });
  };
  
  // 添加创意包删除方法
  const deleteCreativePackage = (index: number) => {
    if (creativePackage.value.length <= 1) return;
  
    creativePackage.value.splice(index, 1);
  
    // 如果删除的是当前选中的创意包，则选中第一个创意包
    if (activeIndex.value === index) {
      activeIndex.value = 0;
    } else if (activeIndex.value > index) {
      // 如果删除的是当前选中创意包之前的创意包，则当前选中的索引减1
      activeIndex.value--;
    }
  };
  </script>
  
  <style scoped lang="less">
  .creative-method {
    color: #1890ff;
  }
  
  .batch-btn {
    margin-right: 10px;
    background-color: #52c41a;
    border-color: #52c41a;
  }
  
  .material-container {
    border: 1px solid #e8e8e8;
    border-radius: 4px;
  }
  
  .top {
    display: flex;
    justify-content: space-between;
    padding: 10px;
    border-bottom: 1px solid #e8e8e8;
    align-items: center;
    flex-wrap: nowrap;
  }
  
  .package-container {
    overflow-x: auto;
    max-width: calc(100% - 150px);
    scrollbar-width: thin;
    scrollbar-color: #d9d9d9 #f0f0f0;
    padding: 8px;
    white-space: nowrap;
    min-width: 300px;
    flex: 1;
  
    &::-webkit-scrollbar {
      height: 6px;
    }
  
    &::-webkit-scrollbar-track {
      background: #f0f0f0;
      border-radius: 3px;
    }
  
    &::-webkit-scrollbar-thumb {
      background-color: #d9d9d9;
      border-radius: 3px;
    }
  }
  
  .package {
    display: inline-flex;
    min-width: max-content;
  
    &-item {
      display: inline-block;
      padding: 8px 15px;
      margin-right: 15px;
      cursor: pointer;
      border-radius: 4px;
      position: relative;
      transition: background-color 0.3s;
      background-color: #f5f5f5;
      border: 1px solid #e8e8e8;
      white-space: nowrap;
  
      &:hover {
        background-color: #e6f7ff;
      }
  
      &.active {
        background-color: #e6f7ff;
        border: 1px solid #1890ff;
        color: #1890ff;
      }
    }
  }
  
  .delete-icon {
    position: absolute;
    top: -8px;
    right: -8px;
    width: 16px;
    height: 16px;
    background-color: #ff4d4f;
    color: white;
    border-radius: 50%;
    text-align: center;
    line-height: 14px;
    font-size: 12px;
    cursor: pointer;
    z-index: 10;
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
  }
  
  .add-package-btn {
    white-space: nowrap;
    flex-shrink: 0;
    width: 120px;
  }
  
  .content {
    padding: 15px;
    display: flex;
    flex-direction: column;
    height: 400px;
  }
  
  .type-container {
    display: flex;
    margin-bottom: 15px;
    gap: 10px;
  }
  
  .type-item {
    width: 130px;
    height: 60px;
    border: 1px solid #e8e8e8;
    border-radius: 4px;
    display: flex;
    align-items: center;
    padding: 0 10px;
    cursor: pointer;
    transition: all 0.3s;
    background-color: #fff;
    position: relative;
  
    &:hover {
      border-color: #40a9ff;
    }
  
    &.active {
      border: 1px solid #1890ff;
      position: relative;
  
      &::after {
        content: "";
        position: absolute;
        top: 0;
        right: 0;
        width: 0;
        height: 0;
        border-style: solid;
        border-width: 0 20px 20px 0;
        border-color: transparent #1890ff transparent transparent;
      }
    }
  }
  
  .type-icon {
    width: 36px;
    height: 36px;
    margin-right: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 4px;
  }
  
  .material-icon {
    width: 28px;
    height: 28px;
  }
  
  .type-name {
    font-size: 14px;
    color: #333;
  }
  
  .tip {
    background-color: #f9f9f9;
    padding: 10px;
    font-size: 12px;
    color: #666;
  }
  
  .tip-content {
    font-size: 11px;
    color: #666;
    line-height: 1.4;
  }
  
  .help-text {
    color: #1890ff;
    cursor: pointer;
  }
  
  .materials-wrapper {
    flex: 1;
    overflow-y: auto;
    min-height: 250px;
    scrollbar-width: thin;
    scrollbar-color: #d9d9d9 #f0f0f0;
  
    &::-webkit-scrollbar {
      width: 6px;
    }
  
    &::-webkit-scrollbar-track {
      background: #f0f0f0;
      border-radius: 3px;
    }
  
    &::-webkit-scrollbar-thumb {
      background-color: #d9d9d9;
      border-radius: 3px;
    }
  }
  
  .materials {
    display: flex;
    flex-wrap: wrap;
    overflow-x: auto;
    padding-bottom: 10px;
    scrollbar-width: thin;
    scrollbar-color: #d9d9d9 #f0f0f0;
    width: 100%;
  }
  
  .material-item {
    width: 120px;
    height: 120px;
    margin-right: 15px;
    margin-bottom: 15px;
    border: 1px solid #e8e8e8;
    border-radius: 4px;
    flex-shrink: 0;
    position: relative;
    overflow: visible;
    padding: 5px;
    margin-top: 15px;
  
    &:hover {
      .replace-material,
      .change-cover {
        opacity: 1;
      }
    }
  }
  
  .material-content {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
  
    img {
      max-width: 100%;
      max-height: 100%;
      object-fit: contain;
    }
  }
  
  .delete-material {
    position: absolute;
    top: -10px;
    right: -10px;
    width: 20px;
    height: 20px;
    background-color: #ff4d4f;
    color: white;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 16px;
    cursor: pointer;
    opacity: 1;
    z-index: 1000;
    box-shadow: 0 3px 6px rgba(0, 0, 0, 0.3);
    pointer-events: auto;
    border: 2px solid white;
  }
  
  .add-material {
    width: 120px;
    height: 120px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px dashed #d9d9d9;
    border-radius: 4px;
    cursor: pointer;
    position: relative;
    flex-shrink: 0;
    margin-top: 15px;
  
    &:hover {
      .add-options {
        display: block;
      }
    }
  }
  
  .add-options {
    position: absolute;
    bottom: -80px;
    left: 0;
    width: 100%;
    background-color: white;
    border: 1px solid #e8e8e8;
    border-radius: 4px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
    z-index: 10;
    display: none;
  }
  
  .option-btn {
    padding: 8px 12px;
    border-bottom: 1px solid #e8e8e8;
    cursor: pointer;
  
    &:hover {
      background-color: #f0f0f0;
    }
  
    &:last-child {
      border-bottom: none;
    }
  }
  
  .add-icon {
    font-size: 24px;
    color: #999;
  }
  
  .modal-footer {
    display: flex;
    justify-content: flex-end;
    margin-top: 20px;
  }
  
  .cancel-btn {
    margin-right: 10px;
  }
  
  :deep(.ant-form-item-label) {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    flex-shrink: 0;
  }
  
  :deep(.ant-form-item) {
    display: flex;
    flex-wrap: nowrap;
  }
  
  :deep(.ant-form-item-control) {
    flex: 1;
    min-width: 0;
  }
  
  .material-count {
    position: absolute;
    top: -8px;
    right: -8px;
    min-width: 16px;
    height: 16px;
    background-color: #ff4d4f;
    color: white;
    border-radius: 8px;
    font-size: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 4px;
    z-index: 5;
  }
  
  .preview-container {
    display: flex;
    flex-direction: column;
    width: 300px;
  }
  
  .preview-info {
    padding: 8px 10px;
    background-color: #f5f5f5;
    border-top-left-radius: 4px;
    border-top-right-radius: 4px;
  }
  
  .preview-name {
    font-size: 14px;
    font-weight: 500;
    color: #333;
    margin-bottom: 4px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  
  .preview-size {
    font-size: 12px;
    color: #666;
  }
  
  .preview-content {
    max-width: 300px;
    max-height: 300px;
    overflow: hidden;
    display: flex;
    justify-content: center;
    align-items: center;
    background-color: #000;
    border-bottom-left-radius: 4px;
    border-bottom-right-radius: 4px;
  }
  
  .preview-image {
    max-width: 100%;
    max-height: 300px;
    object-fit: contain;
  }
  
  .video-preview-container {
    position: relative;
    width: 100%;
    height: 100%;
  }
  
  .preview-video {
    width: 100%;
    max-height: 300px;
    object-fit: contain;
  }
  
  .video-duration {
    position: absolute;
    bottom: 10px;
    right: 10px;
    background-color: rgba(0, 0, 0, 0.7);
    color: white;
    padding: 2px 6px;
    border-radius: 4px;
    font-size: 12px;
    z-index: 10;
  }
  
  .group-item {
    display: flex;
    margin-right: 15px;
    margin-bottom: 15px;
    position: relative;
    margin-top: 15px;
  }
  
  .group-material-item {
    width: 120px;
    height: 120px;
    margin-right: 5px;
    margin-bottom: 0;
    margin-top: 0;
  
    &:last-child {
      margin-right: 0;
    }
  }
  
  .group-delete {
    top: -10px;
    right: -10px;
  }
  
  .replace-material {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    height: 30px;
    background-color: rgba(24, 144, 255, 0.8);
    color: white;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.3s;
    z-index: 900;
  }
  
  .replace-icon {
    display: none;
  }
  
  .data-source-tip {
    font-size: 12px;
    color: #52c41a;
    margin-bottom: 5px;
    padding: 0 5px;
    position: absolute;
    top: -20px;
    left: 10px;
  }
  
  .group-warning {
    color: #ff4d4f;
    font-size: 12px;
    margin-bottom: 10px;
    padding: 5px 10px;
    background-color: #fff2f0;
    border: 1px solid #ffccc7;
    border-radius: 4px;
  }
  
  .video-material {
    width: 100%;
    height: 120px;
    padding: 5px;
  }
  
  .video-info,
  .cover-info {
    display: flex;
    flex-direction: column;
    width: 100%;
    margin-bottom: 5px;
  }
  
  .video-label,
  .cover-label {
    font-size: 12px;
    color: #666;
    margin-bottom: 3px;
    background-color: #f0f0f0;
    padding: 2px 6px;
    border-radius: 2px;
    text-align: center;
  }
  
  .video-thumbnail,
  .cover-thumbnail {
    position: relative;
    width: 100%;
    height: 45px;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    border: 1px solid #e8e8e8;
    border-radius: 4px;
  }
  
  .video-image,
  .cover-image {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
  }
  
  .video-indicator {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: rgba(0, 0, 0, 0.2);
    pointer-events: none;
  }
  
  .video-play-icon {
    color: white;
    font-size: 16px;
    background-color: rgba(0, 0, 0, 0.5);
    width: 24px;
    height: 24px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  
  .change-cover {
    position: absolute;
    bottom: 30px;
    left: 0;
    width: 100%;
    height: 25px;
    background-color: rgba(82, 196, 26, 0.8);
    color: white;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.3s;
    z-index: 900;
  }
  
  .replace-material {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    height: 25px;
    background-color: rgba(24, 144, 255, 0.8);
    color: white;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.3s;
    z-index: 900;
  }
  
  .video-selection-container {
    display: flex;
    width: 100%;
    height: 100%;
    gap: 5px;
  }
  
  .video-selection-box,
  .cover-selection-box {
    flex: 1;
    height: 100%;
    border: 1px dashed #d9d9d9;
    border-radius: 4px;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    aspect-ratio: 2/1;
  }
  
  .video-preview,
  .cover-preview {
    width: 100%;
    height: 100%;
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    background-color: #f5f5f5;
  
    img {
      max-width: 100%;
      max-height: 100%;
      object-fit: contain;
    }
  }
  
  .video-empty,
  .cover-empty {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: #f5f5f5;
    cursor: pointer;
  }
  
  .select-text {
    font-size: 14px;
    color: #1890ff;
    text-align: center;
  }
  
  .cover-options {
    display: flex;
    flex-direction: column;
    width: 100%;
    background-color: #f0f0f0;
  }
  
  .option-btn {
    padding: 4px 0;
    text-align: center;
    font-size: 12px;
    color: #666;
    cursor: pointer;
    border-top: 1px solid #e8e8e8;
  
    &:hover {
      background-color: #e6f7ff;
      color: #1890ff;
    }
  }
  
  .video-indicator {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: rgba(0, 0, 0, 0.2);
    pointer-events: none;
  }
  
  .video-play-icon {
    color: white;
    font-size: 20px;
    background-color: rgba(0, 0, 0, 0.5);
    width: 30px;
    height: 30px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  
  .video-material-item {
    width: 240px !important;
    height: 120px !important;
  }
  
  .add-creatives-btn {
    padding: 8px 16px;
    background-color: #1890ff;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    margin-bottom: 16px;
  }
  
  .creatives-list {
    display: flex;
    flex-direction: column;
    gap: 16px;
    margin-top: 16px;
  }
  
  .creative-package-item {
    border: 1px solid #e8e8e8;
    border-radius: 8px;
    overflow: hidden;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  }
  
  .creative-package-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px 16px;
    background-color: #f5f7fa;
    border-bottom: 1px solid #e8e8e8;
  }
  
  .creative-package-title {
    font-weight: 500;
    font-size: 16px;
    color: #333;
  }
  
  .creative-package-actions {
    display: flex;
    gap: 8px;
  }
  
  .action-btn {
    padding: 4px 12px;
    border-radius: 4px;
    border: none;
    cursor: pointer;
    font-size: 14px;
  }
  
  .edit-btn {
    background-color: #1890ff;
    color: white;
  }
  
  .delete-btn {
    background-color: #ff4d4f;
    color: white;
  }
  
  .creative-package-content {
    padding: 16px;
  }
  
  .creative-materials-preview {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
  }
  
  .material-thumbnail {
    width: 80px;
    height: 80px;
    border-radius: 4px;
    overflow: hidden;
    position: relative;
    border: 1px solid #e8e8e8;
  
    img {
      width: 100%;
      height: 100%;
      object-fit: cover;
    }
  }
  
  .video-indicator {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: rgba(0, 0, 0, 0.3);
  }
  
  .video-icon {
    color: white;
    font-size: 24px;
  }
  
  .preview-details {
    display: flex;
    justify-content: space-between;
    font-size: 12px;
    color: #666;
  }
  
  .preview-dimensions {
    color: #1890ff;
  }
  </style>
  